/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin			*/
/*	Project:	GlbCloud			*/
/*	Author:		gong_libin			*/
/*	Date:		2012_09_13			*/
/*	File:		MrPro.h				*/
/********************************************************/

#ifndef _MRPRO_H
#define	_MRPRO_H

#include "MrDef.h"
#include "MrUtl.h"
#include <arpa/inet.h>

/* head size */
#define	MR_PRO_EXPA			4
#define	MR_PRO_HEAD			12

/* flag */
#define	MR_PRO_FLAG			0xe8

/* protocol type */
#define	MR_PRO_CTRL			0x00
#define	MR_PRO_DATA			0x01

/* no or yes */
#define	MR_PRO_N			0x00
#define	MR_PRO_Y			0x01

/* 0 or 1 */
#define	MR_PRO_0			0x00
#define	MR_PRO_1			0x01

typedef struct tagMrProHead
{
	UCHAR m_ucFlag;
	UCHAR m_ucVersion;
	UCHAR m_ucProtocol;
	UCHAR m_ucReal;
	UCHAR m_ucResponse;
	UCHAR m_ucExpand;
	UCHAR m_ucType;
	UCHAR m_ucVerb;
	UCHAR m_ucAttr;
	UCHAR m_ucResult;
	USHORT m_usTotal;
	int m_iLength;
}MRPROHEAD_S;

class CMrPro
{
public:
	CMrPro();
	virtual ~CMrPro();

	UCHAR MrProGetFlag();
	UCHAR MrProGetReal();
	UCHAR MrProGetType();
	UCHAR MrProGetVerb();
	UCHAR MrProGetAttr();
	int MrProGetLength();
	USHORT MrProGetTotal();
	UCHAR MrProGetExpand();
	UCHAR MrProGetResult();
	UCHAR MrProGetVersion();
	UCHAR MrProGetProtocol();
	UCHAR MrProGetResponse();

	UCHAR* MrProGetBody();
	UCHAR* MrProGetExHead();
	MRPROHEAD_S* MrProGetHead();

	void MrProPutFlag(UCHAR ucFlag);
	void MrProPutReal(UCHAR ucReal);
	void MrProPutType(UCHAR ucType);
	void MrProPutVerb(UCHAR ucVerb);
	void MrProPutAttr(UCHAR ucAttr);
	void MrProPutLength(int iLength);
	void MrProPutTotal(USHORT usTotal);
	void MrProPutExpand(UCHAR ucExpand);
	void MrProPutResult(UCHAR ucResult);
	void MrProPutVersion(UCHAR ucVersion);
	void MrProPutProtocol(UCHAR ucProtocol);
	void MrProPutResponse(UCHAR ucResponse);

	void MrProPutBody(UCHAR* puszBody);
	void MrProPutExHead(UCHAR* puszExHead);
	void MrProPutHead(MRPROHEAD_S* pstHead);

	void MrProReset();
	void MrProDisplay();
	void MrProClone(CMrPro& rCPro);
	void MrProInduce(MRPROHEAD_S* pstHead);
	void MrProParse(UCHAR* puszPacket, int iLength);
	void MrProCreate(UCHAR* puszPacket, int iLength);

	void MrProRequest(UCHAR* puszPacket);
	void MrProResponse(UCHAR* puszPacket);

private:
	UCHAR* m_puszBody;
	MRPROHEAD_S m_stHead;
	UCHAR m_uszExHead[MR_PRO_EXPA];

};

/* WKV */
typedef struct tagMrProWKv
{
	USHORT m_usKey;
	UCHAR* m_puszValue;
}MRPROWKV_S;

void MrProWKvSet(MRPROWKV_S* pstWKv, UCHAR* puszPacket);

/* KV */
#define	MR_PRO_KEYLEN			(sizeof(UCHAR) + sizeof(int))

typedef struct tagMrProKv
{
	UCHAR m_ucKey;
	int m_iLength;
	UCHAR* m_puszValue;
}MRPROKV_S;

MRPROKV_S* MrProKvMalloc(USHORT usTotal, int iSize);
void MrProKvFree(MRPROKV_S** ppstKv, USHORT usTotal);
void MrProKvDisplay(MRPROKV_S* pstKv, USHORT usTotal);
void MrProKvReset(MRPROKV_S* pstKv, USHORT usTotal, int iSize);
int MrProKvInput(MRPROKV_S* pstKv, USHORT usTotal, UCHAR* puszPacket, int iLength);
int MrProKvOutput(MRPROKV_S* pstKv, USHORT usTotal, UCHAR* puszPacket, int iLength);

/* WKLV */
#define	MR_PRO_WKLV			(sizeof(USHORT) + sizeof(int))
typedef struct tagMrProWKlv
{
	USHORT m_usKey;
	int m_iLength;
	UCHAR* m_puszValue;
}MRPROWKLV_S;

void MrProWKlvInput(MRPROWKLV_S* pstWKlv, UCHAR* puszPacket);
void MrProWKlvOutPut(MRPROWKLV_S* pstWKlv, UCHAR* puszPacket);

#endif /* _MRPRO_H */
